#include <cassert>
#include "SudokuSolver.h"

SudokuSolver::SudokuTile::SudokuTile() :
   rowNum(0), 
   colNum(0), 
   boxNum(0),
   possibleValues(511)
{
   // Settings done in initializer list above
}

void SudokuSolver::SudokuTile::setRowNum(int newNum)
{
   assert(newNum >= 0 && newNum <= 9);
   rowNum = newNum;
}

void SudokuSolver::SudokuTile::setColNum(int newNum)
{
   assert(newNum >= 0 && newNum <= 9);
   colNum = newNum;
}

void SudokuSolver::SudokuTile::setBoxNum(int newNum)
{
   assert(newNum >= 0 && newNum <= 9);
   boxNum = newNum;
}

void SudokuSolver::SudokuTile::setValue(int newNum)
{
   assert(newNum >= 0 && newNum <= 9);
   possibleValues = 1 << (newNum - 1);
}

SudokuSolver::TileType SudokuSolver::SudokuTile::getValue(void) const
{
   switch (possibleValues)
   {
   case 1:
      return 1;
   case 2:
      return 2;
   case 4:
      return 3;
   case 8:
      return 4;
   case 16:
      return 5;
   case 32:
      return 6;
   case 64:
      return 7;
   case 128:
      return 8;
   case 256:
      return 9;
   default:
      return 0;
   }
}

bool SudokuSolver::SudokuTile::comparePossible(const SudokuSolver::SudokuTile& in)
{
   return possibleValues == in.possibleValues;
}

int SudokuSolver::SudokuTile::numPossible(void)
{
   int count = 0;
   for (int x = 1; x <= 9; x++)
      count += this->isPossible(x);
   return count;
}

bool SudokuSolver::SudokuTile::removePossible(const SudokuSolver::TileType val)
{
   //assert(val >= 1 && val <= 9);
   const SudokuSolver::TileType savedValues = possibleValues;
   possibleValues &= ~(1 << (val-1));
   if (savedValues < possibleValues)
      assert(false);
   if (savedValues != possibleValues)
      return true;
   else
      return false;
}

bool SudokuSolver::SudokuTile::isPossible(const SudokuSolver::TileType val) const
{
   return (possibleValues & (1 << (val - 1))) > 0;
}